﻿package daphne.noterun.menus
{
	import daphne.noterun.objects.Note;
	import daphne.noterun.notes.PlatformGenerator;
	import daphne.noterun.objects.Player;
	import daphne.noterun.shader.ShaderBin;
	import daphne.noterun.utilities.MidiBin;
	import daphne.noterun.menus.Room;
	import daphne.noterun.events.MyEventDispatcher;
	import daphne.noterun.events.MidiLoadEvent;
	import flash.display.Sprite;
	
	import fl.motion.ITween;
	import flash.display.DisplayObject;
	import flash.display.Shape;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import org.si.sion.SiONData;
	
	import flash.display.Shader;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;
	import flash.net.FileReference;
	import flash.net.FileReferenceList;
	import flash.net.FileFilter;

	import org.si.sion.SiONDriver;
	import org.si.sion.events.*;
	import org.si.sion.midi.*;
	
	public class Main extends MovieClip
	{
		public static var STAGE_WIDTH:int;
		public static var STAGE_HEIGHT:int;
		
		public static var soundDriver:SiONDriver = new SiONDriver(4096);
		
		public var smfData:SMFData = new SMFData();
		private var midiLoader:URLLoader;
		
		private var room:Room;
		private var shaderBin:ShaderBin;
		private var midiBin:MidiBin;
		
		private var buttonContainer:Sprite;
		
		private var fileReference:FileReference;
		
		public function Main()
		{
			super();
			
			STAGE_WIDTH = this.stage.stageWidth;
			STAGE_HEIGHT = this.stage.stageHeight;
			
			MyEventDispatcher.getInstance().addEventListener(MidiLoadEvent.ALL_FINISHED, showMenus);

			this.shaderBin = new ShaderBin();
			this.midiBin = new MidiBin();
			
			//fileReference = new FileReference();
			//The fileSelected function will be called when the users selects a file
			//fileReference.addEventListener(Event.SELECT, midiFileSelected);
			//The browse method receives an array of FileFilters
			//fileReference.browse([new FileFilter("Midi Files", "*.mid;*.midi;*.xml")]);

			//this.stage.addEventListener(MouseEvent.MOUSE_DOWN, mousePressed);
			
			////////////note stuff
			//this.midiLoader = new URLLoader()
			//try
			//{
				//this.midiLoader.dataFormat = URLLoaderDataFormat.BINARY;
				//this.midiLoader.load(new URLRequest("midi/figleaf.mid"));
				//this.midiLoader.addEventListener(Event.COMPLETE, midiLoadFromURLComplete);
			//}
			//catch (e:Error)
			//{
				//trace("Failed to load file: " + e);
			//}
		}
		
		public function showMenus(event:MidiLoadEvent)
		{
			MyEventDispatcher.getInstance().removeEventListener(MidiLoadEvent.ALL_FINISHED, showMenus);

			var buttons:Array = [
								new StartLevelButton(this.midiBin.getDataFor(MidiBin.LEVEL_1)),
								new StartLevelButton(this.midiBin.getDataFor(MidiBin.LEVEL_2)),
								new StartLevelButton(this.midiBin.getDataFor(MidiBin.LEVEL_2)),
								new StartLevelButton(this.midiBin.getDataFor(MidiBin.LEVEL_1)),
								new StartLevelButton(this.midiBin.getDataFor(MidiBin.LEVEL_2))];
			var button:StartLevelButton;
			for each (button in buttons)
			{
				button.addEventListener(MouseEvent.CLICK, mousePressed);
			}
			this.buttonContainer = this.addObjectsInGrid(buttons);
			this.buttonContainer.x = 100;
			this.buttonContainer.y = 100;
			this.addChild(this.buttonContainer);
		}
		
		public function midiFileSelected(event:Event)
		{
			fileReference.removeEventListener(Event.SELECT, midiFileSelected);
			
			fileReference.addEventListener(Event.COMPLETE, midiFileLoaded);
			fileReference.load();
		}
		
		public function midiFileLoaded(event:Event)
		{
			fileReference.removeEventListener(Event.COMPLETE, midiFileLoaded);
			
			var midiData:ByteArray = fileReference.data;
						
			this.smfData.loadBytes(midiData);

			//startLevel();
		}
		
		public function midiLoadFromURLComplete(event:Event)
		{
			trace("MIDI LOAD COMPLETED");
			this.midiLoader.removeEventListener(Event.COMPLETE, midiLoadFromURLComplete);
			var midiData:ByteArray = midiLoader.data as ByteArray;
			this.smfData.loadBytes(midiData);
			
			//startLevel();
		}
		
		private function startLevel(smfData:SMFData):void
		{
			this.room = new Room(STAGE_WIDTH, STAGE_HEIGHT, soundDriver, shaderBin);
			this.addChild(this.room);
			this.room.initGameObjects();
			
			this.addEventListener(Event.ENTER_FRAME, update);
			
			//soundDriver.volume = 0;
			soundDriver.play(smfData);
			//soundDriver.sequenceOnMidi(smfData);
		}
		
		var thing:int = 0;
		
		private function mousePressed(event:MouseEvent):void
		{
			var hitButton:StartLevelButton = event.currentTarget as StartLevelButton;
			
			this.removeChild(buttonContainer);
			
			this.startLevel(hitButton.getSoundData());
			//this.room.midiDriver.stop();
			//this.room.tracks.stopMovement();
		}
		
		function addObjectsInGrid(objects:Array, numCols:int = 2, gap:Number = 2):Sprite {
			var gridContainer:Sprite = new Sprite();
			// numObjects is the number of objects in the array
			var numObjects:int = objects.length;
			var column:int = 0;
			var row:int = 0;
			var gap:Number = 2;
			var cell:DisplayObject;
			for (var i:int = 0; i < numObjects; i++) {
				column = i % numCols;
				row = int(i / numCols);
				// get corresponding object from the array
				cell = objects[i];
				cell.x = (cell.width + gap) * column;
				cell.y = (cell.height + gap) * row;
				gridContainer.addChild(cell);
				trace(i, "\tcolumn =", column, "row =", row);
			}
			//gridContainer.x = gridContainer.y = 20;
			//addChild(gridContainer);
			return gridContainer;
		}

		public function update(event:Event)
		{			
			if (this.room != null)
			{
				room.update(event);
			}
		}
	}
}